define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'vue'], function ($, undefined, Backend, Table, Form, Vue) {
    let Gan = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']
    let Zhi = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
    let zodiacs = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪']
    var Controller = {
        index: function () {
            var vm = new Vue({
                el: '#app',
                data() {
                    return {
                        year: '',
                        month: '',
                        nowMonth: '', //当前月
                        nowYear: '', //当前年
                        day: '', //今天
                        formatMonth: '', //格式化的月份
                        oneDayWeek: '', //月第一个星期
                        days: '', //月多少天
                        lunarYearCn: '', //农历天干地支纪年
                        zodiacYear: '', //农历生肖年
                        calendarPrice: [],
                        festival:{},
                        lunarFestival: {
                            '0101': '春节',
                            '0102': '初二',
                            '0115': '元宵节',
                            '0505': '端午节',
                            '0707': '七夕节',
                            '0715': '中元节',
                            '0815': '中秋节',
                            '0909': '重阳节',
                            '1208': '腊八节',
                            '1223': '小年',
                            '0100': '除夕'
                        },
                        oldPrice: -1
                    }
                },
                computed: {
                    hasHoliday() {
                        return item => {
                            return (item.festival || item.lunarVal || (item.holiday && item.holiday.holiday)) || item.lunar.solarTerm;
                        }
                    },
                    isDisabled() {
                        return item => {
                            return (item.year == this.nowYear && item.month == this.nowMonth && parseInt(item.day) < this.day) || (item.month < this.nowMonth && item.year <= this.nowYear) || item.hasOrderCalendar
                        }
                    }
                },
                created() {
                    var D = new Date();
                    this.year = this.nowYear = D.getFullYear();
                    this.nowMonth = this.month = D.getMonth();
                    this.day = D.getDate();
                    this.render();
                },
                methods: {
                    //渲染
                    async render() {
                        this.festival =  {
                            '0101': '元旦',
                            '0214': '情人节',
                            '0308': '妇女节',
                            '0312': '植树节',
                            '0401': '愚人节',
                            '0501': '劳动节',
                            '0504': '青年节',
                            '0701': '建党节',
                            '0801': '建军节',
                            '0910': '教师节',
                            '1001': '国庆节',
                            '1144': '感恩节',
                            '1224': '平安夜',
                            '1225': '圣诞节'
                        };
                        this.calendarPrice = [];
                        this.formatMonth = (this.month + 1).toString().padStart(2, '0');
                        let oneDayWeek = new Date(Date.parse(this.year + '/' + this.formatMonth + '/' + '01')).getDay();

                        let day;
                        //母亲节 5月第二个星期天
                        if (this.month == 4) {
                            day = (15 - (!oneDayWeek ? 7 : oneDayWeek)).toString().padStart(2, '0');
                            this.$set(this.festival, `05${day}`, '母亲节');
                        }
                        //父亲节 6月第三个星期天
                        if (this.month == 5) {
                            day = (22 - (!oneDayWeek ? 7 : oneDayWeek)).toString().padStart(2, '0');
                            this.$set(this.festival, `06${day}`, '父亲节');
                        }

                        let days = new Date(this.year, this.formatMonth, 0).getDate();

                        //获取数据
                        let param = await this.getServerData();
                        let holidays = typeof Config.holidays == 'object' ? Config.holidays : {};
                        // 传入 offset 传回干支, 0=甲子
                        this.lunarYearCn = this.cyclical(this.year - 1900 + 36);
                        this.zodiacYear = zodiacs[(this.year - 4) % 12];

                        //补上个月
                        let u_m = this.month;
                        let u_y = this.year;
                        if (this.month == 0) {
                            u_m = 11;
                            u_y--;
                        } else {
                            u_m--;
                        }
                        let c_d = (new Date(u_y, u_m + 1, 0).getDate()) - oneDayWeek; //上个月的第几天开始
                        for (let j = 1; j <= oneDayWeek; j++) {
                            let lunar = this.getLunarCalendar(u_y, u_m, j + c_d); //农历
                            this.pushData(
                                param,
                                holidays,
                                lunar,
                                (u_m + 1).toString().padStart(2, '0'),
                                (c_d + j).toString().padStart(2, '0'),
                                u_y,
                                u_m,
                                0
                            );
                            if (lunar.lunarMonth == 1 && lunar.lunarDay == 1) {
                                this.calendarPrice[j - 2].lunarVal = '除夕';
                            }
                        }
                        //当前月
                        for (let i = 0; i < days; i++) {
                            let lunar = this.getLunarCalendar(this.year, this.month, i + 1); //农历
                            this.pushData(
                                param,
                                holidays,
                                lunar,
                                (this.month + 1).toString().padStart(2, '0'),
                                (i + 1).toString().padStart(2, '0'),
                                this.year,
                                this.month,
                                1
                            );
                            if (lunar.lunarMonth == 1 && lunar.lunarDay == 1) {
                                this.calendarPrice[oneDayWeek + i - 1].lunarVal = '除夕';
                            }
                        }

                        //补齐下个月
                        let n_m = this.month;
                        let n_y = this.year;
                        if (this.month == 11) {
                            n_m = 0;
                            n_y++;
                        } else {
                            n_m++;
                        }
                        let nextOneDayWeek = new Date(Date.parse(n_y + '/' + (n_m + 1) + '/' + '01')).getDay();
                        for (let k = 0; k < (7 - nextOneDayWeek); k++) {
                            let lunar = this.getLunarCalendar(n_y, n_m, k + 1); //农历
                            this.pushData(
                                param,
                                holidays,
                                lunar,
                                (n_m + 1).toString().padStart(2, '0'),
                                (k + 1).toString().padStart(2, '0'),
                                n_y,
                                n_m,
                                2
                            );
                            if (lunar.lunarMonth == 1 && lunar.lunarDay == 1) {
                                this.calendarPrice[days + oneDayWeek + k - 1].lunarVal = '除夕';
                            }
                        }
                        this.oneDayWeek = oneDayWeek;
                        this.days = days;
                    },
                    //日历赋值
                    pushData(param, holidays, lunar, formatMonth, formatDay, year, month, status) {
                        let list = param.list || {};
                        let order_calendar = param.orderCalendar || {};
                        this.calendarPrice.push({
                            price: list[`${formatMonth}-${formatDay}`] || (Config.house && Config.house.price) || 0,
                            year: year,
                            month: month,
                            formatMonth: formatMonth,
                            day: formatDay,
                            hasOrderCalendar: order_calendar[`${formatMonth}-${formatDay}`] || null,
                            status: status,
                            festival: this.festival[`${formatMonth}${formatDay}`] || '',
                            lunarVal: this.lunarFestival[`${lunar.lunarMonth.toString().padStart(2, '0')}${lunar.lunarDay.toString().padStart(2, '0')}`] || '',
                            lunar: lunar,
                            holiday: holidays[`${formatMonth}-${formatDay}`]
                        });
                    },
                    //上个月
                    toUp() {
                        if (this.month == 0) {
                            this.month = 11;
                            this.year--;
                        } else {
                            this.month--;
                        }
                        this.render();
                    },
                    //下个月
                    toNext() {
                        if (this.month == 11) {
                            this.month = 0;
                            this.year++;
                        } else {
                            this.month++;
                        }
                        this.render();
                    },
                    cutMonth(item) {
                        if (item.status == 0) {
                            this.toUp();
                        } else if (item.status == 2) {
                            this.toNext();
                        }
                    },
                    focus(item) {
                        this.oldPrice = item.price;
                    },
                    //失去焦点保存数据
                    async confirm(item) {
                        if (item.price == this.oldPrice) {
                            return;
                        }
                        if (item.price < 0) {
                            Toastr.error('价格不能小于0');
                            return;
                        }
                        if (item.price == 0) {
                            await this.isConfirm();
                        }
                        $.post('booking/calendar/add', {
                            house_id: Config.house_id,
                            price: item.price,
                            day_time: `${item.year}-${item.formatMonth}-${item.day}`
                        }, function (res) {
                            if (res.code == 1) {
                                Toastr.success(res.msg);
                            } else {
                                Toastr.error(res.msg);
                            }
                        })
                    },
                    isConfirm() {
                        return new Promise((resolve, reject) => {
                            var index = Layer.confirm('您确定修改价格为0吗？', {
                                btn: ['确定', '取消'] //按钮
                            }, function () {
                                Layer.close(index)
                                resolve()
                            }, function () {});
                        })
                    },
                    //一个月的价格日历
                    getServerData() {
                        return new Promise((resolve, reject) => {
                            $.get(`booking/calendar/index?year=${this.year}&month=${this.month+1}&house_id=${Config.house_id}`, function (res) {
                                if (res.code == 1) {
                                    resolve(res.data);
                                } else {
                                    resolve({});
                                }
                            })
                        })
                    },
                    cyclical(num) {
                        return (Gan[num % 10] + Zhi[num % 12])
                    },
                    //获取农历
                    getLunarCalendar(GY, GM, GD) {

                        let lunarInfo = [
                            0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
                            0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
                            0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
                            0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
                            0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
                            0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
                            0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
                            0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
                            0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
                            0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
                            0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
                            0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
                            0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
                            0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
                            0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0
                        ]

                        //==== 传回农历 year年的总天数
                        function lYearDays(year) {
                            let i, sum = 348
                            for (i = 0x8000; i > 0x8; i >>= 1) {
                                sum += (lunarInfo[year - 1900] & i) ? 1 : 0
                            }
                            return (sum + leapDays(year))
                        }

                        //==== 传回农历 year年闰月的天数
                        function leapDays(year) {
                            if (leapMonth(year)) {
                                return ((lunarInfo[year - 1900] & 0x10000) ? 30 : 29)
                            } else {
                                return 0
                            }
                        }

                        //==== 传回农历 year年闰哪个月 1-12 , 没闰传回 0
                        function leapMonth(year) {
                            return (lunarInfo[year - 1900] & 0xf)
                        }

                        //==== 传回农历 year年month月的总天数
                        function monthDays(year, month) {
                            return ((lunarInfo[year - 1900] & (0x10000 >> month)) ? 30 : 29)
                        }

                        //==== 算出农历, 传入日期对象, 传回农历日期对象
                        //     该对象属性有 农历年year 农历月month 农历日day 是否闰年isLeap yearCyl dayCyl monCyl
                        function Lunar(objDate) {
                            let i, temp = 0
                            let baseDate = new Date(1900, 0, 31)
                            let offset = Math.floor((objDate - baseDate) / 86400000)

                            let dayCyl = offset + 40
                            let monCyl = 14

                            for (i = 1900; i < 2050 && offset > 0; i++) {
                                temp = lYearDays(i)
                                offset -= temp
                                monCyl += 12
                            }
                            if (offset < 0) {
                                offset += temp;
                                i--;
                                monCyl -= 12
                            }
                            //农历年
                            let year = i
                            let yearCyl = i - 1864

                            let leap = leapMonth(i) //闰哪个月
                            let isLeap = false //是否闰年

                            for (i = 1; i < 13 && offset > 0; i++) {
                                //闰月
                                if (leap > 0 && i === (leap + 1) && isLeap === false) {
                                    --i;
                                    isLeap = true;
                                    temp = leapDays(year);
                                } else {
                                    temp = monthDays(year, i);
                                }

                                //解除闰月
                                if (isLeap === true && i === (leap + 1)) {
                                    isLeap = false
                                }

                                offset -= temp
                                if (isLeap === false) {
                                    monCyl++
                                }
                            }

                            if (offset === 0 && leap > 0 && i === leap + 1)
                                if (isLeap) {
                                    isLeap = false
                                }
                            else {
                                isLeap = true
                                    --i
                                    --monCyl
                            }

                            if (offset < 0) {
                                offset += temp
                                    --i
                                    --monCyl
                            }
                            //农历月
                            let month = i
                            //农历日
                            let day = offset + 1

                            return {
                                year: year,
                                month: month,
                                day: day,
                                isLeap: isLeap,
                                leap: leap,
                                yearCyl: yearCyl,
                                dayCyl: dayCyl,
                                monCyl: monCyl
                            }
                        }

                        //==== 中文日期 m为传入月份，d为传入日期
                        function cDay(m, d) {
                            let nStr1 = ['日', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
                            let nStr2 = ['初', '十', '廿', '卅', '']
                            //农历中文月
                            let lunarMonthCn
                            //农历中文日
                            let lunarDayCn
                            if (m > 10) {
                                lunarMonthCn = '十' + nStr1[m - 10]
                            } else {
                                lunarMonthCn = nStr1[m]
                            }
                            lunarMonthCn += '月'

                            switch (d) {
                                case 10:
                                    lunarDayCn = '初十';
                                    break;
                                case 20:
                                    lunarDayCn = '二十';
                                    break;
                                case 30:
                                    lunarDayCn = '三十';
                                    break;
                                default:
                                    lunarDayCn = nStr2[Math.floor(d / 10)] + nStr1[d % 10]
                            }
                            return {
                                lunarMonthCn: lunarMonthCn,
                                lunarDayCn: lunarDayCn
                            }
                        }

                        //节气
                        function getSolarTerm() {
                            let sTermInfo = [
                                0, 21208, 42467, 63836, 85337, 107014,
                                128867, 150921, 173149, 195551, 218072, 240693,
                                263343, 285989, 308563, 331033, 353350, 375494,
                                397447, 419210, 440795, 462224, 483532, 504758
                            ]
                            let solarTerm = [
                                '小寒', '大寒', '立春', '雨水', '惊蛰', '春分',
                                '清明', '谷雨', '立夏', '小满', '芒种', '夏至',
                                '小暑', '大暑', '立秋', '处暑', '白露', '秋分',
                                '寒露', '霜降', '立冬', '小雪', '大雪', '冬至'
                            ]

                            let solarTerms = ''
                            let tmp1 = new Date(
                                (31556925974.7 * (GY - 1900) + sTermInfo[GM * 2 + 1] * 60000) + Date.UTC(1900, 0, 6, 2, 5)
                            )
                            let tmp2 = tmp1.getUTCDate()
                            if (tmp2 === GD) solarTerms = solarTerm[GM * 2 + 1]
                            tmp1 = new Date(
                                (31556925974.7 * (GY - 1900) + sTermInfo[GM * 2] * 60000) + Date.UTC(1900, 0, 6, 2, 5)
                            )
                            tmp2 = tmp1.getUTCDate()
                            if (tmp2 === GD) solarTerms = solarTerm[GM * 2]

                            return solarTerms
                        }
                        const calendar = {
                            lunarYear: null, //农历年
                            lunarMonth: null, //农历月
                            lunarDay: null, //农历日
                            lunarMonthCn: '', //农历中文月
                            lunarDayCn: '', //农历中文日
                            solarTerm: '', //节气
                        }
                        //去掉时分秒的日期
                        let sDObj = new Date(GY, GM, GD);
                        let lDObj = new Lunar(sDObj);
                        //农历年月日、生肖年
                        calendar.lunarYear = lDObj.year
                        calendar.lunarMonth = lDObj.month
                        calendar.lunarDay = lDObj.day
                        //农历中文年月日
                        calendar.lunarMonthCn = cDay(lDObj.month, lDObj.day).lunarMonthCn
                        calendar.lunarDayCn = cDay(lDObj.month, lDObj.day).lunarDayCn
                        //节气
                        calendar.solarTerm = getSolarTerm();
                        return calendar;
                    }
                }
            })

        },
        add: function () {
            Controller.api.bindevent();
        },
        edit: function () {
            Controller.api.bindevent();
        },
        api: {
            bindevent: function () {
                Form.api.bindevent($("form[role=form]"));
            }
        }
    };
    return Controller;
});
